<?php
namespace Cola;
/**
 *
 */

class View
{
    /**
     * view file
     *
     * @var string
     */
    public $file;
    
    /**
     * 模板变量
     * @var array
     */
    protected $data = [];

    /**
     * Constructor
     *
     * @param string $file
     */
    public function __construct($file)
    {
        $this->file = $file;
    }

    /**
     * Fetch
     *
     * @return string
     */
    public function fetch()
    {
        ob_start();
        ob_implicit_flush(0);
        $this->display();
        return ob_get_clean();
    }

    /**
     * Display
     *
     * @param null|string $_Lam_layout
     */
    public function display($_Lam_layout = null)
    {
        // 增加ob系列函数 edit by suika
        ob_start();
        ob_implicit_flush(0);
        extract($this->data);

        include $this->file;

        if($_Lam_layout && is_file($_Lam_layout))
        {
            $_Lam_content = ob_get_clean();

            preg_match_all('#\{LamTag:header\}([\s\S]+)\{/LamTag:header\}|\{LamTag:footer\}([\s\S]+)\{/LamTag:footer\}#', $_Lam_content, $_Lam_match);
            empty($_Lam_match[1][0]) && $_Lam_match[1] = [''];
            empty($_Lam_match[2]) && $_Lam_match[2] = ['', ''];

            ob_start();
            include $_Lam_layout;

            // 替换布局的主体内容
            $_Lam_content = str_replace('{__CONTENT__}', $_Lam_content, ob_get_clean());
            // 将主模板中的LamTag:header标签和LamTag:footer标签转移到指定位置
            $_Lam_content = preg_replace([
                '#\{__LAMTAGHEAD__\}#',
                '#\{LamTag:header\}([\s\S]+)\{/LamTag:header\}#i',
                '#\{__LAMTAGFOOT__\}#',
                '#\{LamTag:footer\}([\s\S]+)\{/LamTag:footer\}#i'
            ], [
                $_Lam_match[1][0],
                '',
                $_Lam_match[2][0] ? : ($_Lam_match[2][1]??''),
                ''
            ], $_Lam_content);

            unset($_Lam_match);
            echo $_Lam_content;
        }
        else
        {
            echo ob_get_clean();
        }
    }

    /**
     * Escape
     *
     * @param string $str
     * @param string $type
     * @param string $encoding
     * @return string
     */
    public static function escape($str, $type = 'html', $encoding = 'UTF-8')
    {
        switch ($type) {
            case 'html':
                return htmlspecialchars($str, ENT_QUOTES, $encoding);

            case 'htmlall':
                return htmlentities($str, ENT_QUOTES, $encoding);

            case 'javascript':
                return strtr($str, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));

            case 'mail':
                return str_replace(array('@', '.'),array(' [AT] ', ' [DOT] '), $str);

            default:
                return $str;
        }
    }

    /**
     * Truncate
     *
     * @param string $str
     * @param int    $limit
     * @param string $encoding
     * @param string $suffix
     *
     * @return string
     */
    public static function truncate($str, $limit, $encoding = 'UTF-8', $suffix = '...')
    {
        if (mb_strwidth($str, $encoding) <= $limit) return $str;

        $limit -= mb_strwidth($suffix, $encoding);
        $tmp = mb_strimwidth($str, 0, $limit, '', $encoding);
        return $tmp . $suffix;
    }

    /**
     * 模板变量赋值
     *
     * @access public
     *
     * @param array|string $key
     * @param mixed $value 变量值
     *
     * @return $this
     */
    public function assign($key, $value = '')
    {
    	if(is_array($key) && $key)
    	{
    		foreach($key as $k => $v)
    		{
    			$this->data[$k] = $v;
    		}
    	}else
    	{
    		$this->data[$key] = $value;
    	}
    	return $this;
    }

    /**
     * Dynamic set vars
     *
     * @param string $key
     * @param mixed $value
     */
    public function __set($key, $value = null)
    {
    	$this->data[ $key ] = $value;
    	// $this->$key = $value;
    }

    /**
     * Dynamic get vars
     *
     * @param string $key
     *
     * @return Config|null
     */
    public function __get($key)
    {
        switch ($key) {
            case 'config':
                return Cola::getInstance()->config();
            default:
                return null;
        }
    }
}